package com.qili.service.zx.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.qili.annotation.Mean;
import com.qili.base.mapper.BaseMapper;
import com.qili.base.service.impl.BaseServiceImpl;
import com.qili.entity.base.BaseDict;
import com.qili.entity.base.BaseMilepost;
import com.qili.entity.base.BaseMilepostZx;
import com.qili.entity.jc.JcProject;
import com.qili.entity.jc.dto.JcProjectStageDTO;
import com.qili.entity.supervisor.*;
import com.qili.entity.supervisor.dto.SupervisorProjectDTO;
import com.qili.entity.supplier.ProjectPlace;
import com.qili.entity.supplier.SupplierProject;
import com.qili.entity.supplier.dto.ProjectPlaceDTO;
import com.qili.entity.sys.SysUser;
import com.qili.entity.sys.dto.SysUserDTO;
import com.qili.entity.zx.*;
import com.qili.entity.zx.dto.ZxProjectDTO;
import com.qili.entity.zx.dto.ZxProjectMilepostDTO;
import com.qili.entity.zx.dto.ZxProjectStageDTO;
import com.qili.exception.MyException;
import com.qili.mapper.base.BaseDictMapper;
import com.qili.mapper.supervisor.ProjectNoticeMapper;
import com.qili.mapper.supplier.ProjectPlaceMapper;
import com.qili.mapper.sys.SysUserMapper;
import com.qili.mapper.zx.ZxProjectMapper;
import com.qili.service.base.BaseDictService;
import com.qili.service.base.BaseMilepostZxService;
import com.qili.service.supervisor.ProjectLeaderService;
import com.qili.service.supervisor.ProjectUnitConstructionService;
import com.qili.service.supervisor.SupervisorFileService;
import com.qili.service.supplier.SupplierProjectManagerService;
import com.qili.service.zx.*;
import com.qili.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhaoyongke
 * @date 2021/6/24
 * @description
 */
@Slf4j
@Service
public class ZxProjectServiceImpl extends BaseServiceImpl<ZxProject,String> implements ZxProjectService {


    @Autowired
    private ZxProjectMapper zxProjectMapper;
    @Autowired
    private ProjectPlaceMapper projectPlaceMapper;
    @Autowired
    private ZxProjectMilepostService zxProjectMilepostService;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    SupplierProjectManagerService supplierProjectManagerService;
    @Autowired
    private ProjectLeaderService projectLeaderService;
    @Autowired
    BaseDictMapper baseDictMapper;
    @Autowired
    private ProjectNoticeMapper projectNoticeMapper;
    @Autowired
    private ProjectUnitConstructionService projectUnitConstructionService;
    @Autowired
    private ZxProjectStageService zxProjectStageService;
    @Autowired
    private ZxProjectPayService payService;
    @Autowired
    private ZxProjectModifiedRecordService modifiedRecordService;

    @Autowired
    private BaseDictService baseDictService;
    @Autowired
    private SupervisorFileService supervisorFileService;
    @Autowired
    private BaseMilepostZxService baseMilepostService;

    @Override
    public BaseMapper<ZxProject, String> getMappser() {
        return zxProjectMapper;

    }


    @Override
    public void addPalce(ZxProjectDTO zxProjectDTO) throws Exception{
        List<ProjectPlaceDTO> personPlacedtos = zxProjectDTO.getProjectPlacedtos();
        if(personPlacedtos != null){
            for (int i = 0; i <personPlacedtos.size() ; i++) {
                ProjectPlaceDTO dto= personPlacedtos.get(i);
                if(StringUtil.isNotBlank(dto.getProvince())){
                    ProjectPlace place=new ProjectPlace();
                    BeanUtil.copyNotNullBean(dto, place);
                    place.setType("001");// 001 实施地点 002 人员要求地点
                    place.setProPlaceId(IdUtil.simpleUUID());
                    place.setSupProjectId(zxProjectDTO.getProjectId());
                    projectPlaceMapper.insertSelective(place);
                }
            }
        }

    }

    /**
     * @param ids
     * @Author:Zhangshuo
     * @Description: 删除回收站项目
     * @Date:20:33 2020-12-11
     */
    @Override
    public int deleteProjectsFromRecycle(String[] ids) {
        return zxProjectMapper.deleteProjectsFromRecycle(ids);
    }

    @Override
    public List<ZxProjectDTO> selectZxProject(ZxProjectDTO dto) {
        return zxProjectMapper.selectZxProject(dto);
    }

    /**
     * @param dto
     * @Author:zhaoyongke
     * @Description: 查询项目
     * @Date:15:48 2020/11/26
     */
    public List<ZxProjectDTO> selectSupervisorProject(ZxProjectDTO dto) {
        return zxProjectMapper.selectSupervisorProject(dto);
    }

    /*
     * 删除项目
     * */
    @Override
    public JsonUtil del(String id) {
        JsonUtil j = new JsonUtil();
        try {
            deleteByPrimaryKey(id);
            j.setMsg("删除成功");
        } catch (MyException e) {
            j.setMsg("删除失败");
            j.setFlag(false);
            e.printStackTrace();
        }
        return j;
    }

    @Override
    public void updateProjectStatusAfterMilepostFinish(ZxProjectMilepost milepost) {
        if ("002".equals(milepost.getMilepostNo())) {
            String  projectId=milepost.getProjectId();
            ZxProject projectselect=zxProjectMapper.selectByPrimaryKey(projectId);
            String status=projectselect.getStatus();
            //001 未提交
            //002 未启动
            //003 已完成
            //004 进行中
            //005 已延期
            //如果该里程是  合同  ，那么设置项目状态为进行中
            ZxProject project = new ZxProject();
            project.setId(milepost.getProjectId());
            if("005".equals(status)){
                //判断有没有延期的阶段
                ZxProjectMilepost  milepostYc=new ZxProjectMilepost();
                milepostYc.setProjectId(milepost.getProjectId());
                milepostYc.setFinishStatus("3");
                int  countjd=zxProjectMilepostService.selectCount(milepostYc);
                if(countjd>0){
                    // 存在延期的阶段
                    project.setStartTime(DateUtil.getCurrentDateString());
                }else{
                    project.setStatus("004");
                    project.setStartTime(DateUtil.getCurrentDateString()) ;
                }

            }else{
                project.setStatus("004");
                project.setStartTime(DateUtil.getCurrentDateString());
            }
            zxProjectMapper.updateByPrimaryKeySelective(project);

        }
    }

    @Override
    public void updateProjectStatusAfterStageFinish(ZxProjectStage stage) {
        // 判断除 其他检测工作 以外 其他的阶段是否都完成
        Boolean  isfinish=true;
        ZxProjectStageDTO dto = new ZxProjectStageDTO();
        dto.setProjectId(stage.getProjectId());
        dto.setNotStageNo("005");
        List<ZxProjectStageDTO> listStage = zxProjectStageService.selectProjectStage(dto);

        if(listStage!=null  &&  listStage.size()>0){
            for (int i = 0; i < listStage.size(); i++) {
                ZxProjectStageDTO  stagedto=listStage.get(i);
                String finishDate = stagedto.getFinishDate();
                if(StringUtil.isBlank(finishDate)){
                    isfinish=false;
                    break;
                }
            }
        }
        if(isfinish){
            ZxProject projectselect=zxProjectMapper.selectByPrimaryKey(stage.getProjectId());
            String statusxm=projectselect.getStatus();
            if(StringUtils.isBlank(projectselect.getFinishDate())){
                /*发送消息提醒*/
                sendNoticePj(projectselect.getId());
            }
            //验收阶段结束，设置项目状态为已完成
            ZxProject project = new ZxProject();
            project.setId(stage.getProjectId());
            project.setStatus("003");
            project.setFinishDate(DateUtil.getCurrentDateTimeString());
            zxProjectMapper.updateByPrimaryKeySelective(project);
        }
    }
    /**
     * @Author:zhaoyongke
     * @Description:
     * @Date:17:54 2021/1/22
     */
    public void sendNoticePj(String  projectId){
        ZxProject project=zxProjectMapper.selectByPrimaryKey(projectId);
        if(StringUtils.isBlank(project.getProjectSource())){
            throw new RuntimeException("发送评价通知时,项目来源为空!");
        }
        /*项目发布人*/
        String createUser=project.getCreateBy();
        SysUser sysUser=sysUserMapper.selectUserById(createUser);
        /*发布人是正中的 001  */
        String source=sysUser.getSource();
        if("001".equals(source)){
            /*发布人是正中的  */
            // （1）评价市场人员（对项目发布人--正中的）  002 供需
            if("002".equals(project.getProjectSource())){
                HashMap mapsc=getPjScRy(project);
                saveToNotice(mapsc,"012", project,source);
            }
            //  (2) 对项目经理评价
            HashMap xmjlpj= getPjXmjl(project,true);
            saveToNotice(xmjlpj,"011", project,source);
        }else{
            /*发布人不是是正中的  评价供方（监理项目经理）*/
            HashMap  xmjlpj= getPjXmjl(project,false);
            saveToNotice(xmjlpj,"011", project,"003");
        }
    }
    /**
     * @Author:zhaoyongke
     * @Description: 获取对发布人的评价的----评价人
     * @Date:17:38 2021/1/22
     */
    public  HashMap  getPjScRy(ZxProject project){
        // （1）评价市场人员（对项目发布人--正中的）
        HashMap  map=new HashMap();
        // 评价人员  监理的项目经理  总监 技术负责人 项目审核人  业主单位的所有负责人  拥有质控角色的人员
        /*监理项目经理*/
        String managerPerson=project.getProjectManagerPerson();
        map.put("jlxmjl",managerPerson);
        //总监理工程师
        String zjl=project.getSupervisorEngineer();
        map.put("zjl",zjl);
        // 技术负责人
        String jsfz=project.getTechnologyPerson();
        map.put("jsfz",jsfz);
        //项目审核人
        SupplierProject supplierProject = getSupplierProjectBySupervisorProject(project);
        if(supplierProject != null && StringUtils.isNotBlank(supplierProject.getCheckBy())){
            map.put("xmshr",supplierProject.getCheckBy());
        }
        // 业主单位的所有负责人
        ProjectLeader projectLeader = new ProjectLeader();
        projectLeader.setSupervisorProjectId(project.getId());
        List<ProjectLeader> selectleader = projectLeaderService.select(projectLeader);
        for (int i = 0; i < selectleader.size(); i++) {
            ProjectLeader leader = selectleader.get(i);
            String projectLeaderstr = leader.getProjectLeader();
            String key="yz"+i;
            map.put(key,projectLeaderstr);
        }
        // 拥有质控角色的人员
        SysUserDTO sysUserDTO=new SysUserDTO();
        sysUserDTO.setUserRole("zkjsry");
        List<SysUser>  sysUsers=sysUserMapper.getUserDicts(sysUserDTO);
        for (int i = 0; i < sysUsers.size(); i++) {
            String userId=sysUsers.get(i).getId();
            String key="zk"+i;
            map.put(key,userId);
        }
        return  map;
    }
    /**
     * 根据监理项目获取对应的供需项目
     * @param project
     * @return
     */
    private SupplierProject getSupplierProjectBySupervisorProject(ZxProject project) {
        if(project != null && StringUtils.isNotBlank(project.getSupProjectId())){
            return supplierProjectManagerService.selectByPrimaryKey(project.getSupProjectId());
        }
        return null;
    }
    /**
     * @Author:zhaoyongke
     * @Description: 发送通知
     * @param map
     * @param pjType
     * @Date:17:55 2021/1/22
     */
    public void saveToNotice(HashMap  map, String pjType, ZxProject project, String userSource){
        List<BaseDict>  baseDicts=baseDictMapper.getDicList("PJ001");
        String pjday="";
        for (int i = 0; i < baseDicts.size(); i++) {
            pjday=baseDicts.get(i).getBadtLevel1();
        }
        if(StringUtil.isBlank(pjday)){
            pjday="30";
        }
        Iterator iter = map.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            if(entry.getKey()!=null && entry.getValue()!=null ){
                String roleName = entry.getKey().toString();
                String userId = entry.getValue().toString();
                ProjectNotice notice=new ProjectNotice();
                notice.setNoticeId(IdUtil.simpleUUID());
                notice.setLinkId(project.getId());
                notice.setIsView("0");
                notice.setSendTo(userId);
                notice.setPjRole(roleName);
                notice.setPjType(pjType);// 011 对项目经理评价 012  对 发布人评价
                if("011".equals(pjType)){
                    //正中人员发布的自主项目,评价实施人员改为项目评价  并且不显示评价市场人员
                    if("001".equals(userSource) && "002".equals(project.getProjectSource())){
                        notice.setTitle(project.getProjectName()+"项目完成，请在"+pjday+"天之内评价实施人员");
                    }else{
                        notice.setTitle(project.getProjectName()+"项目完成，请在"+pjday+"天之内评价项目");
                    }

                }else if("012".equals(pjType)){
                    notice.setTitle(project.getProjectName()+"项目完成，请在"+pjday+"天之内评价市场人员");
                }
                notice.setNoticeType("003");//通知类型 账号通知 001  002 流程进展通知  003 评价通知
                notice.setApplicantType("003");// 监理
                notice.setCreateBy(CommonUtil.getUserId());
                notice.setCreateDate(DateUtil.getCurrentDateString());
                projectNoticeMapper.insertSelective(notice);
            }
        }
    }

    /**
     * @Author:zhaoyongke
     * @Description:  获取对项目经理的评价人员
     * @param project
     * @Date:17:39 2021/1/22
     */
    public  HashMap  getPjXmjl(ZxProject project, Boolean  isZzFb){
        //评价人 业主单位的所有负责人  承建单位的所有负责人  拥有质控角色的人员   发布人是正中的发布人  项目审核人
        HashMap  map=new HashMap();
        //(1)业主单位的所有负责人
        ProjectLeader projectLeader = new ProjectLeader();
        projectLeader.setSupervisorProjectId(project.getId());
        List<ProjectLeader> selectleader = projectLeaderService.select(projectLeader);
        for (int i = 0; i < selectleader.size(); i++) {
            ProjectLeader leader = selectleader.get(i);
            String projectLeaderstr = leader.getProjectLeader();
            String key="yz"+i;
            map.put(key,projectLeaderstr);
        }
        //(2)承建单位的所有负责人
        ProjectUnitConstruction projectUnitConstruction = new ProjectUnitConstruction();
        projectUnitConstruction.setSupervisorProjectId(project.getId());
        List<ProjectUnitConstruction> selectunit=projectUnitConstructionService.select(projectUnitConstruction);
        for (int i = 0; i <selectunit.size() ; i++) {
            String projectManager=selectunit.get(i).getProjectManager();
            String key="cj"+i;
            map.put(key,projectManager);
        }
        //拥有质控角色的人员
        SysUserDTO sysUserDTO=new SysUserDTO();
        sysUserDTO.setUserRole("zkjsry");
        List<SysUser>  sysUsers=sysUserMapper.getUserDicts(sysUserDTO);
        for (int i = 0; i < sysUsers.size(); i++) {
            String userId=sysUsers.get(i).getId();
            String key="zk"+i;
            map.put(key,userId);
        }
        //2021-03-11 新增拥有公司高层角色的人员
//        SysUserDTO companyTop =new SysUserDTO();
//        companyTop.setUserRole("gsgc");
//        List<SysUser>  companyTops = sysUserMapper.getUserDicts(companyTop);
//        for (int i = 0; i < companyTops.size(); i++) {
//            String userId=companyTops.get(i).getId();
//            String key="gsgc"+i;
//            map.put(key,userId);
//        }
        //2021-05-07增加项目发布人:
        SupplierProject supplierProject = getSupplierProjectBySupervisorProject(project);
        if(supplierProject != null && StringUtils.isNotBlank(supplierProject.getPublishBy())){
            map.put("xmfbr",supplierProject.getPublishBy());
        }
//        //2021-05-07增加项目审核人
//        if(supplierProject != null && StringUtils.isNotBlank(supplierProject.getCheckBy())){
//            map.put("xmshr",supplierProject.getCheckBy());
//        }
        return  map;
    }

    @Override
    public BigDecimal calProgress(Object obj) throws ParseException {
        ZxProject project = new ZxProject();
        BigDecimal projectProgress = new BigDecimal("0.00");
        if (obj.getClass() == ZxProjectStage.class) {
            //阶段完成,计算进度
            ZxProjectStage stage = (ZxProjectStage) obj;
            //验证是否已经计算过了各阶段的占比
            if (!checkStageProgress(stage.getProjectId())) {
                setProjectStageProgress(stage.getProjectId());
            }
            projectProgress = calProjectProgressFinishedStage(stage, 2);
            project.setId(stage.getProjectId());
        } else if (obj.getClass() == ZxProjectMilepost.class) {
            //里程完成,阶段未完成,计算进度
            ZxProjectMilepost milepost = (ZxProjectMilepost) obj;
            if (!checkStageProgress(milepost.getProjectId())) {
                setProjectStageProgress(milepost.getProjectId());
            }
            projectProgress = calProjectProgressFinishedMilepost(milepost);
            project.setId(milepost.getProjectId());
        }
        BigDecimal hun = new BigDecimal("100");
        if (projectProgress.compareTo(hun) == 1) {
            projectProgress = hun;
            // 百分之百 就设置为 完成
            project.setStatus("003");
            if(StringUtils.isBlank(project.getFinishDate())){
                /*发送消息提醒*/
                sendNoticePj(project.getId());
            }
            project.setFinishDate(DateUtil.getCurrentDateTimeString());
        }
        if (projectProgress.compareTo(hun) == 0) {
            // 百分之百 就设置为 完成
            project.setStatus("003");
            if(StringUtils.isBlank(project.getFinishDate())){
                /*发送消息提醒*/
                sendNoticePj(project.getId());
            }
            project.setFinishDate(DateUtil.getCurrentDateTimeString());
        }
        String status="";
        if(StringUtil.isNotBlank(project.getId())){
            ZxProject zxProject = zxProjectMapper.selectByPrimaryKey(project.getId());
            status=zxProject.getStatus();
        }
        project.setProgress(projectProgress.toString());
        log.info("计算出来的项目进度:"+projectProgress.toString());
        if("002".equals(status)){
            project.setProgress(new BigDecimal("0.00").toString());
            projectProgress = new BigDecimal("0.00");
        }
        zxProjectMapper.updateByPrimaryKeySelective(project);
        return projectProgress;
    }

    @Override
    public ZxProjectDTO getOldProjectInfo(ZxProjectDTO oldProjectInfo) {
        ZxProject oldProject = selectByPrimaryKey(oldProjectInfo.getId());
        oldProjectInfo = JSON.parseObject(JSON.toJSONString(oldProject), ZxProjectDTO.class);
        //查询项目阶段：
        ZxProjectStage stage = new ZxProjectStage();
        stage.setProjectId(oldProjectInfo.getId());
        List<ZxProjectStage> stageList = zxProjectStageService.select(stage);
        if(stageList!=null && stageList.size()>0){
            oldProjectInfo.setZxProjectStages((ArrayList)stageList);
        }
        //查询付款节点：
        ZxProjectPay pay = new ZxProjectPay();
        pay.setSppPrjid(oldProjectInfo.getId());
        List<ZxProjectPay> projectPays = payService.select(pay);
        if(projectPays!=null && projectPays.size()>0){
            oldProjectInfo.setPayList((ArrayList)projectPays);
        }
        return oldProjectInfo;
    }

    @Override
    public void compareProject(ZxProjectDTO oldObject, ZxProjectDTO newObject, String userId) {
        try {
            String fkfs = "";
            //遍历所有的字段,然后动态调用get方法
            if (oldObject.getClass() == newObject.getClass()) {
                Class clazz = oldObject.getClass();
                //获取object的所有属性
                PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz, Object.class).getPropertyDescriptors();
                for (PropertyDescriptor pd : pds) {
                    //遍历获取属性名
                    Mean mean = getMeanByFieldName(clazz,pd.getName());
                    if (mean != null) {
                        //说明改属相上有Mean注解，是需要记录修改情况的：
                        //获取属性的get方法
                        Method readMethod = pd.getReadMethod();
                        // 在oldObject上调用get方法等同于获得oldObject的属性值
                         Object oldValue = readMethod.invoke(oldObject);
                        // 在newObject上调用get方法等同于获得newObject的属性值
                        Object newValue = readMethod.invoke(newObject);
                        if("是否续签".equals(mean.value())){
                            if("000".equals(oldValue)){
                                oldValue = "否";
                            }else{
                                oldValue = "是";
                            }
                            if("000".equals(newValue)){
                                newValue = "否";
                            }else{
                                newValue = "是";
                            }
                        }
                        if("项目类型".equals(mean.value())){
                                oldValue = zxProjectMapper.queryXmlx((String)oldValue);
                                newValue = zxProjectMapper.queryXmlx((String)newValue);
                        }
                        if("付款方式".equals(mean.value())){
                            fkfs = newValue.toString();
                            if("1".equals(oldValue)){
                                oldValue = "付款节点";
                            }else{
                                oldValue = "付款时间";
                            }
                            if("1".equals(newValue)){
                                newValue = "付款节点";
                            }else{
                                newValue = "付款时间";
                            }
                        }
                        if("是否需要招投标".equals(mean.value()) || "是否已招标".equals(mean.value()) || "是否已签合同".equals(mean.value()) || "是否有首付款".equals(mean.value())){
                            if("0".equals(oldValue)){
                                oldValue = "否";
                            }else{
                                oldValue = "是";
                            }
                            if("0".equals(newValue)){
                                newValue = "否";
                            }else{
                                newValue = "是";
                            }
                        }
                        if("合同签订地点(省)".equals(mean.value()) || "合同签订地点(城市)".equals(mean.value()) || "合同签订地点(区县)".equals(mean.value())){
                            oldValue = zxProjectMapper.querySsdq((String)oldValue);
                            newValue = zxProjectMapper.querySsdq((String)newValue);

                        }
                        if("行业类型".equals(mean.value())){
                            oldValue = zxProjectMapper.queryHy((String)oldValue);
                            newValue = zxProjectMapper.queryHy((String)newValue);
                        }
                        if("咨询工程师".equals(mean.value())){
                            String[] args = oldValue.toString().split(",");
                            String[] argsn = newValue.toString().split(",");
                            for(int x = 0;x<args.length;x++){
                                SysUser sysUser = sysUserMapper.selectByPrimaryKey(args[x]);
                                String old = "";
                                if(x == 0){
                                    oldValue = "";
                                }
                                if(sysUser != null){
                                    old = sysUser.getRealName();
                                }else {
                                    continue;
                                }

                                if(x==args.length-1){
                                    oldValue = oldValue + old;
                                }else{
                                    oldValue = oldValue + old + ",";
                                }
                            }
                            for(int i = 0;i<argsn.length;i++){
                                SysUser sysUser = sysUserMapper.selectByPrimaryKey(argsn[i]);
                                String old = "";
                                if(i == 0){
                                    newValue = "";
                                }
                                if(sysUser != null){
                                    old = sysUser.getRealName();
                                }else {
                                    continue;
                                }

                                if(i==argsn.length-1){
                                    newValue = newValue + old;
                                }else{
                                    newValue = newValue + old + ",";
                                }
                            }
                        }
                        if("行业负责人".equals(mean.value()) || "项目经理".equals(mean.value())){
                            oldValue = sysUserMapper.selectByPrimaryKey(oldValue.toString());
                            newValue = sysUserMapper.selectByPrimaryKey(newValue.toString());
                        }
                        if("项目归属".equals(mean.value())){
                            oldValue = zxProjectMapper.queryXmgs((String)oldValue);
                            newValue = zxProjectMapper.queryXmgs((String)newValue);
                        }
                        if ((oldValue instanceof ArrayList) && (newValue instanceof ArrayList)) {
                            ArrayList oldValueArrayList = (ArrayList)oldValue;
                            ArrayList newValueArrayList = (ArrayList)newValue;
                            if("项目阶段".equals(mean.value())){
                                //项目阶段比对：
                                compareProjectStages(oldValueArrayList,newValueArrayList);
                            }else if("付款节点".equals(mean.value())){
                                compareProjectPays(oldValueArrayList,newValueArrayList,fkfs);
                            }
                            continue;
                        }
                        if (oldValue == null && newValue == null) {
                            continue;
                        } else if ((newValue != null && (!oldValue.equals(newValue))) || (newValue == null && oldValue!=null)) {

                            ZxProjectModifiedRecord modifiedRecord = new ZxProjectModifiedRecord();
                            modifiedRecord.setSpmrId(IdUtil.simpleUUID());
                            modifiedRecord.setSpField(pd.getName());
                            modifiedRecord.setSpFieldName(mean.value());
                            modifiedRecord.setSpId(newObject.getId());
                            modifiedRecord.setSpmrModifiedBy(userId);
                            modifiedRecord.setSpmrModifiedTime(DateUtil.getCurrentDateTimeString());
                            modifiedRecord.setSpmrAction("修改");
                            if("监理项目经理".equals(mean.value())){
                                //监理项目经理，查询名字
                                SysUser oldUser = sysUserMapper.selectByPrimaryKey(oldValue.toString());
                                SysUser newUser = sysUserMapper.selectByPrimaryKey(newValue.toString());
                                modifiedRecord.setOldValue(oldUser.getRealName());
                                modifiedRecord.setNewValue(newUser.getRealName());
                            }else{
                                modifiedRecord.setOldValue(oldValue.toString());
                                modifiedRecord.setNewValue(newValue.toString());
                            }

                            modifiedRecordService.insertSelective(modifiedRecord);
                            continue;
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 通过字段名称获取Mean注解值
     * @param clazz
     * @param name
     */
    private Mean getMeanByFieldName(Class clazz, String name) {
        Field field = null;
        try {
            field = clazz.getDeclaredField(name);
        } catch (NoSuchFieldException e) {
            //没有属性，去父类中找：
            try {
                field = clazz.getSuperclass().getDeclaredField(name);
            } catch (NoSuchFieldException ne) {
                log.warn("父类中也没有找到这个属性：" + name);
            }
        }
        return field.getAnnotation(Mean.class);
    }

    /**
     * 验证当前项目是否已经设置了阶段的进度
     *
     * @param projectId
     * @return 设置过返回true    没有设置过返回false
     */

    public boolean checkStageProgress(String projectId) throws ParseException {
        //查询数据库
        Example example = new Example(ZxProjectStage.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("projectId", projectId);
        criteria.andIsNull("progress");
        //排除掉其他监理工作  该阶段不参与进度的计算
        criteria.andNotEqualTo("stageNo","005");
        List<ZxProjectStage> ZxProjectStages = zxProjectStageService.selectByExample(example);
        return ZxProjectStages.size() == 0;
    }

    public void setProjectStageProgress(String projectId) throws ParseException {
        //设置项目阶段占比:
        ZxProject supervisorProject = zxProjectMapper.selectByPrimaryKey(projectId);
        ZxProjectStage stage = new ZxProjectStage();
        stage.setProjectId(projectId);
        List<ZxProjectStage> stageList = zxProjectStageService.select(stage);
        for (ZxProjectStage aStage : stageList) {
            if("005".equals(aStage.getStageNo())){
                //005代表了创建项目时往最后加的阶段--其他监理工作  该阶段不参与进度的计算
                continue;
            }
            int dayDiffer = (DateUtil.getDayDiffer(aStage.getStartDate(), aStage.getEndDate()))+1;
            BigDecimal aStageProgress = new BigDecimal(dayDiffer).multiply(new BigDecimal("100")).divide(new BigDecimal(supervisorProject.getTotalDate()), 4, BigDecimal.ROUND_HALF_UP);
            aStage.setProgress(aStageProgress.toString());
            zxProjectStageService.updateByPrimaryKeySelective(aStage);
        }
    }

    /**
     * 当里程完成（阶段未完成）时的项目进度计算
     * @param milepost 里程完成时的当前里程
     * @return
     */
    private BigDecimal calProjectProgressFinishedMilepost(ZxProjectMilepost milepost) {
        BigDecimal result = BigDecimal.ZERO;
        //获取项目所有的阶段：
        ZxProjectStage selectStage = new ZxProjectStage();
        selectStage.setProjectId(milepost.getProjectId());
        List<ZxProjectStage> select = zxProjectStageService.select(selectStage);
        if(select.size() > 0){
            for(ZxProjectStage aStage : select){
                //如果是其他监理阶段，过
                if("005".equals(aStage.getStageNo())){
                    continue;
                }
                BigDecimal stageProgress = new BigDecimal(aStage.getProgress());
                //如果遍历的阶段状态是已经完成，那么需要+该阶段的占比
                if(StringUtils.isNotBlank(aStage.getFinishDate()) && ("2".equals(aStage.getFinishStatus()) || "3".equals(aStage.getFinishStatus()))){
                    //如果这个阶段已经完成：
                    result = result.add(stageProgress);
                }else{
                    //如果该阶段没有完成，那么需要验证该阶段的里程是否有完成的:
                    //获取该阶段已经完成的里程占比   例如0.8
                    BigDecimal finishedMilepostProgressByStage = getFinishedMilepostProgressByMilepost(aStage,milepost);
                    if(null != finishedMilepostProgressByStage && finishedMilepostProgressByStage.compareTo(BigDecimal.ZERO) != 0){
                        BigDecimal thisStageFinishedProgress = stageProgress.multiply(finishedMilepostProgressByStage);
                        result = result.add(thisStageFinishedProgress);
                    }
                }
            }
        }
        result = result.setScale(2,BigDecimal.ROUND_HALF_UP);
        return result;
    }
    /**
     * 获取某个阶段已经完成的里程的占比
     * 当项目里程完成时调用
     * @param milepost
     * @return
     */
    private BigDecimal getFinishedMilepostProgressByMilepost(ZxProjectStage stage, ZxProjectMilepost milepost) {
        BigDecimal result = BigDecimal.ZERO;
        milepost.setSupervisorProjectStageId(stage.getId());
        String finishedMilepostProgress = zxProjectMilepostService.getFinishedMilepostProgress(milepost);
        if(StringUtils.isNotBlank(finishedMilepostProgress)){
            result = new BigDecimal(finishedMilepostProgress).divide(new BigDecimal("100"),4,BigDecimal.ROUND_HALF_UP);
        }
        return result;
    }

    /**
     * 阶段完成时的项目进度计算方法
     * 该方法应该在确保阶段的进度值计算完成后调用
     * @param stage 阶段完成时的当前阶段
     * @return
     */
    private BigDecimal calProjectProgressFinishedStage(ZxProjectStage stage, int scale) {
        BigDecimal result = BigDecimal.ZERO;
        boolean allFinished = checkAllFinished(stage);
        if(allFinished){
            return new BigDecimal("100");
        }
        //获取项目所有的阶段：
        ZxProjectStage selectStage = new ZxProjectStage();
        selectStage.setProjectId(stage.getProjectId());
        List<ZxProjectStage> select = zxProjectStageService.select(selectStage);

        if(select.size() > 0){
            for(ZxProjectStage aStage : select){
                //如果是其他监理阶段，过
                if("005".equals(aStage.getStageNo())){
                    continue;
                }
                BigDecimal stageProgress = new BigDecimal(aStage.getProgress());
                //如果遍历的是正在完成的阶段，或者是已经完成的阶段,那么直接+当前里程占比
                if(stage.getId().equals(aStage.getId())
                        || (StringUtils.isNotBlank(aStage.getFinishDate())
                        && ("2".equals(aStage.getFinishStatus()) || "3".equals(aStage.getFinishStatus())))){
                    result = result.add(stageProgress);
                }else{
                    //如果该阶段没有完成，
                    //获取该阶段已经完成的里程占比和
                    BigDecimal finishedMilepostProgressByStage = getFinishedMilepostProgressByStage(aStage);
                    if(null != finishedMilepostProgressByStage && finishedMilepostProgressByStage.compareTo(BigDecimal.ZERO) != 0){
                        BigDecimal thisStageFinishedProgress = stageProgress.multiply(finishedMilepostProgressByStage);
                        result = result.add(thisStageFinishedProgress);
                    }
                }
            }
        }
        result = result.setScale(2,BigDecimal.ROUND_HALF_UP);
        return result;
    }

    /**
     * 当阶段完成,计算进度的时候调用该方法
     * 判断是否所有的阶段已经完成(排除自己和其他监理工作)
     * @param stage
     * @return      全部完成了,返回true,否则返回false
     */
    private boolean checkAllFinished(ZxProjectStage stage){
        return zxProjectStageService.getNotFinishedStageCount(stage)==0;
    }
    /**
     * 获取某个阶段已经完成的里程的占比
     * 当项目阶段完成时调用
     * @param stage
     * @return
     */
    private BigDecimal getFinishedMilepostProgressByStage(ZxProjectStage stage){
        BigDecimal result = BigDecimal.ZERO;
        String finishedMilepostProgress = zxProjectMilepostService.getFinishedMilepostProgress(stage);
        if(StringUtils.isNotBlank(finishedMilepostProgress)){
            result = new BigDecimal(finishedMilepostProgress).divide(new BigDecimal("100"),4,BigDecimal.ROUND_HALF_UP);
        }
        return result;
    }





    /**
     * 比对项目付款节点变化：
     * 有可能的变化：新增的    删除的    修改的
     * 新增的：newValue里面含有oldValue里面没有的id或者newValue里面没有id
     * 删除的：
     * @param oldProjectPayList
     * @param newProjectPayList
     */
    private void compareProjectPays(ArrayList<ZxProjectPay> oldProjectPayList, ArrayList<ZxProjectPay> newProjectPayList,String fkfs) {

        Map<String, ZxProjectPay> oldProjectPayMap =
                oldProjectPayList.stream().collect(Collectors.toMap(ZxProjectPay::getSppId, oldProjectPay -> oldProjectPay));

        String projectId = oldProjectPayList.get(0).getSppPrjid();
        String userId = CommonUtil.getUserId();
        try {
            Class clazz = ZxProjectPay.class;
            PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz, Object.class).getPropertyDescriptors();
            for (ZxProjectPay newPay : newProjectPayList) {
                if (StringUtils.isBlank(newPay.getSppId()) && (StringUtils.isNotBlank(newPay.getSppNode())||StringUtils.isNotBlank(newPay.getPayDate()))) {
                    //新增的
                    ZxProjectModifiedRecord modifiedRecord = new ZxProjectModifiedRecord();
                    modifiedRecord.setSpmrId(IdUtil.simpleUUID());
                    modifiedRecord.setSpField("projectPay");
                    String percent = "";
                    String milepostName = "";
                    if("2".equals(fkfs)){
                        modifiedRecord.setSpFieldName("付款时间");
                        modifiedRecord.setNewValue(newPay.getPayDate());
                    }else{
                        modifiedRecord.setSpFieldName("付款节点");
                        //获取里程名称：

                        String milepostNo = newPay.getSppNode();
                        if(StringUtils.isNotBlank(milepostNo)){
                            BaseDict baseDict = new BaseDict();
                            baseDict.setBadtTypecode("LC001ZX");
                            baseDict.setBadtCode(milepostNo);
                            List<BaseDict> select = baseDictMapper.select(baseDict);
                            if (select != null && select.size() > 0) {
                                milepostName = select.get(0).getBadtName();
                                modifiedRecord.setSpFieldName("付款节点");
                                modifiedRecord.setNewValue(milepostName + "--" + percent);
                            }
                        }
                    }

                    if(StringUtils.isNotBlank(newPay.getSppPersent())){
                        percent = newPay.getSppPersent();
                    }
                    modifiedRecord.setSpId(projectId);
                    modifiedRecord.setSpmrModifiedBy(userId);
                    modifiedRecord.setSpmrModifiedTime(DateUtil.getCurrentDateTimeString());
                    modifiedRecord.setSpmrAction("新增");
                    modifiedRecord.setOldValue("");
                    modifiedRecordService.insertSelective(modifiedRecord);
                } else {
                    if("-1".equals(newPay.getSppNote())){
                        //这个是删除的：
                        //先看看数据库有没有：
                        ZxProjectPay dbPay = payService.selectByPrimaryKey(newPay.getSppId());
                        if(dbPay != null){
                            ZxProjectModifiedRecord modifiedRecord = new ZxProjectModifiedRecord();
                            modifiedRecord.setSpmrId(IdUtil.simpleUUID());
                            modifiedRecord.setSpField("projectPay");
                            if("2".equals(fkfs)){
                                modifiedRecord.setOldValue(newPay.getPayDate());
                            }else{
                                modifiedRecord.setSpFieldName("付款节点");
                                //获取里程名称：
                                String milepostNo = newPay.getSppNode();
                                BaseDict baseDict = new BaseDict();
                                baseDict.setBadtTypecode("LC001ZX");
                                baseDict.setBadtCode(milepostNo);
                                List<BaseDict> select = baseDictMapper.select(baseDict);
                                if (select != null && select.size() > 0) {
                                    modifiedRecord.setSpFieldName("付款节点");
                                    modifiedRecord.setOldValue(select.get(0).getBadtName() + "--" + newPay.getSppPersent());
                                }
                            }

                            modifiedRecord.setSpId(projectId);
                            modifiedRecord.setSpmrModifiedBy(userId);
                            modifiedRecord.setSpmrModifiedTime(DateUtil.getCurrentDateTimeString());
                            modifiedRecord.setSpmrAction("删除");

                            modifiedRecord.setNewValue("");
                            modifiedRecordService.insertSelective(modifiedRecord);
                        }
                    }else{
                        //修改的：
                        ZxProjectPay oldPay = oldProjectPayMap.get(newPay.getSppId());
                        if(oldPay.getSppPersent()==null&&oldPay.getPayDate()==null&oldPay.getSppNode() == null){
                            continue;
                        }
                        if(newPay.getSppPersent()==null&&newPay.getPayDate()==null&newPay.getSppNode() == null){
                            continue;
                        }
                        for (PropertyDescriptor pd : pds) {
                            //遍历获取属性名
                            Mean mean = getMeanByFieldName(clazz,pd.getName());
                            if (mean != null) {
                                //说明改属相上有Mean注解，是需要记录修改情况的：
                                //获取属性的get方法
                                Method readMethod = pd.getReadMethod();
                                // 在oldObject上调用get方法等同于获得oldObject的属性值
                                Object oldValue = readMethod.invoke(oldPay);
                                // 在newObject上调用get方法等同于获得newObject的属性值
                                Object newValue = readMethod.invoke(newPay);

                                if (oldValue == null && newValue == null) {
                                    continue;
                                } else if ((newValue != null && (!oldValue.equals(newValue))) || (newValue == null && oldValue!=null)) {
                                    ZxProjectModifiedRecord modifiedRecord = new ZxProjectModifiedRecord();
                                    modifiedRecord.setSpmrId(IdUtil.simpleUUID());
                                    modifiedRecord.setSpField(pd.getName());
                                    modifiedRecord.setSpFieldName(mean.value());
                                    List<BaseDict> select = new ArrayList<>();
                                    if(!"付款时间".equals(mean.value())){
                                        //获取里程名称：
                                        String milepostNo = oldPay.getSppNode();
                                        BaseDict baseDict = new BaseDict();
                                        baseDict.setBadtTypecode("LC001ZX");
                                        baseDict.setBadtCode(milepostNo);
                                        select = baseDictMapper.select(baseDict);
                                    }
                                    if("付款节点".equals(mean.value())){
                                        //获取新里程名称：
                                        String newMilepostNo = newPay.getSppNode();
                                        BaseDict newBaseDict = new BaseDict();
                                        newBaseDict.setBadtTypecode("LC001ZX");
                                        newBaseDict.setBadtCode(newMilepostNo);
                                        List<BaseDict> newSelect = baseDictMapper.select(newBaseDict);
                                        modifiedRecord.setOldValue(select.get(0).getBadtName());
                                        modifiedRecord.setNewValue(newSelect.get(0).getBadtName());
                                    }else if("付款比例".equals(mean.value())){
                                        if(select!=null && select.size()>0){
                                            if ("2".equals(fkfs)){
                                                modifiedRecord.setSpFieldName(newPay.getPayDate()+"--"+mean.value());
                                            }else{
                                                modifiedRecord.setSpFieldName(select.get(0).getBadtName()+"--"+mean.value());
                                            }

                                        }
                                        modifiedRecord.setOldValue(oldValue.toString());
                                        modifiedRecord.setNewValue(newValue.toString());
                                    }else if("付款时间".equals(mean.value())){
                                        modifiedRecord.setOldValue(oldValue.toString());
                                        modifiedRecord.setNewValue(newValue.toString());
                                    }
                                    modifiedRecord.setSpId(projectId);
                                    modifiedRecord.setSpmrModifiedBy(userId);
                                    modifiedRecord.setSpmrModifiedTime(DateUtil.getCurrentDateTimeString());
                                    modifiedRecord.setSpmrAction("修改");
                                    modifiedRecordService.insertSelective(modifiedRecord);
                                    continue;
                                }
                            }
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    /**
     * 比对项目阶段变化：
     * 项目对于阶段的变化只有时间的变化，所以根据id判断开始时间和截止时间即可
     * @param oldProjectStageList
     * @param newProjectStageList
     */
    private void compareProjectStages(ArrayList<ZxProjectStage> oldProjectStageList, ArrayList<ZxProjectStage> newProjectStageList) {
        Map<String, ZxProjectStage> oldProjectStageMap =
                oldProjectStageList.stream().collect(Collectors.toMap(ZxProjectStage::getId, oldProjectStage -> oldProjectStage));
//        Map<String, ZxProjectStage> newProjectStageMap =
//                newProjectStageList.stream().collect(Collectors.toMap(ZxProjectStage::getId, newProjectStage -> newProjectStage));
        String projectId = oldProjectStageList.get(0).getProjectId();
        String userId = CommonUtil.getUserId();
        try{
            Class clazz = ZxProjectStage.class;
            PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz, Object.class).getPropertyDescriptors();
            for(ZxProjectStage newStage : newProjectStageList){
                ZxProjectStage oldStage = oldProjectStageMap.get(newStage.getId());
                for (PropertyDescriptor pd : pds) {
                    //遍历获取属性名
                    String name = pd.getName();
                    Field field = null;
                    try {
                        field = clazz.getDeclaredField(name);
                    } catch (NoSuchFieldException e) {
                        //没有属性，去父类中找：
                        try {
                            field = clazz.getSuperclass().getDeclaredField(name);
                        } catch (NoSuchFieldException ne) {
                            log.warn("父类中也没有找到这个属性：" + name);
                        }
                    }
                    Mean mean = field.getAnnotation(Mean.class);
                    if (mean != null) {
                        //说明改属相上有Mean注解，是需要记录修改情况的：
                        //获取属性的get方法
                        Method readMethod = pd.getReadMethod();
                        // 在oldObject上调用get方法等同于获得oldObject的属性值
                        Object oldValue = readMethod.invoke(oldStage);
                        // 在newObject上调用get方法等同于获得newObject的属性值
                        Object newValue = readMethod.invoke(newStage);

                        if (oldValue == null && newValue == null) {
                            continue;
                        } else if ((newValue != null && (!oldValue.equals(newValue))) || (newValue == null && oldValue!=null)) {
                            ZxProjectModifiedRecord modifiedRecord = new ZxProjectModifiedRecord();
                            modifiedRecord.setSpmrId(IdUtil.simpleUUID());
                            modifiedRecord.setSpField(field.getName());
                            modifiedRecord.setSpFieldName(mean.value());
                            //获取阶段名称：
                            String stageNo = oldStage.getStageNo();
                            BaseDict baseDict = new BaseDict();
                            baseDict.setBadtTypecode("JD001");
                            baseDict.setBadtCode(stageNo);
                            List<BaseDict> select = baseDictMapper.select(baseDict);
                            if(select!=null && select.size()>0){
                                modifiedRecord.setSpFieldName(select.get(0).getBadtName()+"--"+mean.value());
                            }
                            modifiedRecord.setSpId(projectId);
                            modifiedRecord.setSpmrModifiedBy(userId);
                            modifiedRecord.setSpmrModifiedTime(DateUtil.getCurrentDateTimeString());
                            modifiedRecord.setSpmrAction("修改");
                            modifiedRecord.setOldValue(oldValue.toString());
                            modifiedRecord.setNewValue(newValue.toString());
                            modifiedRecordService.insertSelective(modifiedRecord);
                            continue;
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public boolean checkFileNecessary(ZxProjectDTO supervisorProjectDTO) {
        BaseDict wjBaci = new BaseDict();
        wjBaci.setBadtTypecode("WJ001ZX");
        wjBaci.setBadtCode(supervisorProjectDTO.getType());
        List<BaseDict> select = baseDictService.select(wjBaci);
        if(select == null || select.size() == 0){
            log.warn("判断某文件是否是必选时,没有找到字典项",supervisorProjectDTO.getType());
        }
        BaseDict fileDict = select.get(0);
        return (StringUtils.isNotBlank(fileDict.getBadtLevel5()) && "1".equals(fileDict.getBadtLevel5()));
    }

    /**
     * @Author:zhaoyongke
     * @Description: 获取用户角色
     * @param fileId
     * @Date:16:42 2021/1/14
     */
    public String getUserRole(String fileId) {
        String rolename="";
        //获取当前用户的角色
        String userId = CommonUtil.getUserId();
        SupervisorFile supervisorFile = supervisorFileService.selectByPrimaryKey(fileId);
        String projectId = supervisorFile.getProjectId();
        ZxProject supervisorProject = zxProjectMapper.selectByPrimaryKey(projectId);
        //项目经理Id(监理单位)
        String projectManager = supervisorProject.getProjectManagerPerson();
        if (userId.equals(projectManager)) {
            /*项目经理*/
            rolename="xmjl";
            return rolename;
        }
        //总监理工程师
        String  zjl=supervisorProject.getSupervisorEngineer();
        if (userId.equals(zjl)) {
            /*总监理*/
            rolename="zjl";
            return rolename;
        }
        //技术负责人
        String technologyPerson= supervisorProject.getTechnologyPerson();
        if (userId.equals(technologyPerson)) {
            /*技术负责人*/
            rolename="jsfzr";
            return rolename;
        }

        /*判断是否是业主单位*/
        Boolean isyz = projectLeaderService.isYzUser(projectId);
        if (isyz) {
            rolename="yz";
            return rolename;
        }
        /*判断是否是承建单位*/
        Boolean iscj = projectUnitConstructionService.isCjUser(projectId);
        if (iscj) {
            rolename="cj";
            return rolename;
        }
        return rolename;
    }

    @Override
    public List<ZxProjectDTO> selectZxJlTjProject(ZxProjectDTO dto) {
        return zxProjectMapper.selectZxJlTjProject(dto);
    }

    @Override
    public String getPayMiseNoDate(ZxProjectStage stage, ZxProjectMilepost milepost) {
        String enddatestr = "";
        /*此方法 两个地方调用 （1） 点击完成按钮 （2） 查看项目*/
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        /*阶段开始时间*/
        String jdStartDatestr = stage.getStartDate();
        /*阶段结束时间*/
        String jdEndDatestr = stage.getEndDate();
        if (StringUtil.isNotBlank(jdStartDatestr) && StringUtil.isNotBlank(jdEndDatestr)) {
            Date jdStarDate = DateUtil.parseDate(jdStartDatestr, "yyyy-MM-dd");
            Date jdEndDate = DateUtil.parseDate(jdEndDatestr, "yyyy-MM-dd");
            /*关键是获取该里程的正常结束时间    用结束时间和里程完成时间比较
             完成时间在里程正常结束时间之前则状态为完成，否则为延期状态*/
            //(1) 通过计算获取里程的正常结束时间
            String baseMilePostId = milepost.getSpmBaseMilePostId();
            BaseMilepostZx baseMilepost = baseMilepostService.selectByPrimaryKey(baseMilePostId);
            if (baseMilepost != null) {
                System.out.println("kongn gjkonmgg ng n" + baseMilepost.getId());
                Integer orderNum = baseMilepost.getOrderNum();
                /*获取本阶段  该里程之前得所有里程*/
                ZxProjectMilepostDTO postdto = new ZxProjectMilepostDTO();
                postdto.setOrderNum(orderNum);
                postdto.setSupervisorProjectStageId(stage.getId());
                List<ZxProjectMilepostDTO> ZxProjectMilepostDTOList = zxProjectMilepostService.selectMilePostOrder(postdto);
                /*遍历里程  计算 百分比*/
                BigDecimal decimal = new BigDecimal(0.0);
                for (int i = 0; i < ZxProjectMilepostDTOList.size(); i++) {
                    String percentage = ZxProjectMilepostDTOList.get(i).getPercentage();
                    BigDecimal bd = new BigDecimal(percentage);
                    decimal = decimal.add(bd);
                }
                Double jddays = (double) ((jdEndDate.getTime() - jdStarDate.getTime()) / (1000 * 3600 * 24));
                int i = decimal.compareTo(BigDecimal.ZERO);
                BigDecimal cs = new BigDecimal("100.00");
                BigDecimal jddaysbig = BigDecimal.valueOf(jddays);
                Integer addday = null;
                if (i != 0) {
                    /*比例不等于0 开始计算*/
                    BigDecimal perbi = decimal.divide(cs, 20, BigDecimal.ROUND_HALF_UP);
                    BigDecimal addDays = jddaysbig.multiply(perbi);
                    // 取大于这个数字得最小整数
                    Double ceil = Math.ceil(addDays.doubleValue());
                    addday = ceil.intValue();
                    Calendar calendar = new GregorianCalendar();
                    calendar.setTime(jdStarDate);
                    if (addday != null) {
                        calendar.add(Calendar.DATE, addday);
                        /*按照比例计算天之后的日期*/
                        /*正常应该完成的时间*/
                    }
                    Date dateend = new Date(calendar.getTimeInMillis());
                    enddatestr = DateUtil.formatDate(dateend, "yyyy-MM-dd");
                    return enddatestr;
                }
            }
        }
        return enddatestr;
    }
    /**
     * @Author:zhaoyongke
     * @Description: 项目完成率
     * @param dto
     * @Date:13:31 2021/5/14
     */
    @Override
    public List<ZxProjectDTO>  selectProFinishLv(ZxProjectDTO dto){
        return zxProjectMapper.selectProFinishLv(dto);
    }

    @Override
    public void resetProgress(String id) {
        ZxProject project = new ZxProjectDTO();
        try {
            this.setProjectStageProgress(id);
            BigDecimal result = BigDecimal.ZERO;
            //获取项目所有的阶段：
            ZxProjectStage selectStage = new ZxProjectStage();
            selectStage.setProjectId(id);
            List<ZxProjectStage> select = zxProjectStageService.select(selectStage);

            if(select.size() > 0){
                for(ZxProjectStage aStage : select){
                    //如果是其他监理阶段，过
                    if("005".equals(aStage.getStageNo())){
                        continue;
                    }
                    BigDecimal stageProgress = new BigDecimal(aStage.getProgress());
                    //如果遍历的是正在完成的阶段，或者是已经完成的阶段,那么直接+当前里程占比
                    if((StringUtils.isNotBlank(aStage.getFinishDate())
                            && ("2".equals(aStage.getFinishStatus()) || "3".equals(aStage.getFinishStatus())))){
                        result = result.add(stageProgress);
                    }else{
                        //如果该阶段没有完成，
                        //获取该阶段已经完成的里程占比和
                        BigDecimal finishedMilepostProgressByStage = getFinishedMilepostProgressByStage(aStage);
                        if(null != finishedMilepostProgressByStage && finishedMilepostProgressByStage.compareTo(BigDecimal.ZERO) != 0){
                            BigDecimal thisStageFinishedProgress = stageProgress.multiply(finishedMilepostProgressByStage);
                            result = result.add(thisStageFinishedProgress);
                        }
                    }
                }
            }
            result = result.setScale(2,BigDecimal.ROUND_HALF_UP);
            project.setId(id);
            BigDecimal hun = new BigDecimal("100");
            if(result.compareTo(hun)==0){
                // 项目进度 100 就设置成已完成
                project.setStatus("003");
                if(StringUtils.isBlank(project.getFinishDate())){
                    /*发送消息提醒*/
                    sendNoticePj(project.getId());
                }
                project.setFinishDate(DateUtil.getCurrentDateTimeString());
            }
            if (result.compareTo(hun) == 1) {
                result = hun;
                // 百分之百 就设置为 完成
                project.setStatus("003");
                if(StringUtils.isBlank(project.getFinishDate())){
                    /*发送消息提醒*/
                    sendNoticePj(project.getId());
                }
                project.setFinishDate(DateUtil.getCurrentDateTimeString());
            }
            // 是否有阶段20220216 zhaoyongke
            Boolean hasJd=false;
            if(StringUtil.isBlank(project.getFinishDate())){
                // 如果 除 其他阶段 都完成  则 项目为完成
                Boolean  isfinish=true;
                ZxProjectStageDTO dto = new ZxProjectStageDTO();
                dto.setProjectId(project.getId());
                dto.setNotStageNo("005");
                List<ZxProjectStageDTO> listStage = zxProjectStageService.selectProjectStage(dto);
                if(listStage!=null  &&  listStage.size()>0){
                    hasJd=true;
                    for (int i = 0; i < listStage.size(); i++) {
                        ZxProjectStageDTO  stagedto=listStage.get(i);
                        String finishDate = stagedto.getFinishDate();
                        if(StringUtil.isBlank(finishDate)){
                            isfinish=false;
                            break;
                        }
                    }

                }
                // 这里需要排除一种情况 （基本信息编辑时，删除各个阶段 也会产生isfinish 为true 的情况） 20220216 zhaoyongke
                if (isfinish && hasJd) {
                    project.setStatus("003");
                    /*发送消息提醒*/
                    sendNoticePj(project.getId());
                    project.setFinishDate(DateUtil.getCurrentDateTimeString());
                }
            }


            project.setProgress(result.toString());
            zxProjectMapper.updateByPrimaryKeySelective(project);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
    @Override
    public  List<ZxProjectDTO> selectZxListApp(ZxProjectDTO dto){
       return  zxProjectMapper.selectZxListApp(dto);
    }
}





